﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;

using ByHand.Data.Interfaces;

namespace ByHand.Data
{
    public abstract class RepositoryBase<T> : IRepository<T> where T : class
    {
        private ByHandDB db;
        private readonly IDbSet<T> dbset;

        /// <summary>
        /// Holds a reference to the DatabaseFactory class used to manage connections to the database.
        /// </summary>
        protected IDatabaseFactory DatabaseFactory { get; private set; }
        /// <summary>
        /// Contains a reference to the <see cref="System.Data.Entity.DbContext"/> instance used by the repository.
        /// </summary>
        protected ByHandDB ByHandDB { get { return db ?? (db = DatabaseFactory.Get()); } }

        /// <summary>
        /// Initialises a new instance of the RepositoryBase class.
        /// </summary>

        public RepositoryBase(IDatabaseFactory DbFactory)
        {
            DatabaseFactory = DbFactory;
            dbset = ByHandDB.Set<T>();
        }

        /// <summary>
        /// Adds a new entity instance to the database on behalf of the parent type.
        /// </summary>
        /// <param name="Entity">Any valid database object</param>
        public virtual void Add(T Entity)
        {
            dbset.Add(Entity);
            db.Commit();
        }

        /// <summary>
        /// Deletes an existing instance of an entity from the database on behalf of the parent type.
        /// </summary>
        /// <param name="Entity">Any valid database object</param>
        public virtual void Delete(T Entity)
        {
            dbset.Remove(Entity);
            db.Commit();
        }

        /// <summary>
        /// Returns a specific instance of an entity from the database on behalf of the parent type.
        /// </summary>
        /// <param name="Id">The integer value of the entity's primary key</param>
        /// <returns>A database object (of type T)</returns>
        public virtual T GetById(int Id)
        {
            return dbset.Find(Id);
        }

        /// <summary>
        /// Returns an IEnumerable collection of all objects found in the database of type T
        /// </summary>
        /// <returns>A collection of type IEnumerable</returns>
        public virtual IEnumerable<T> All()
        {
            return dbset.ToList();
        }

        /// <summary>
        /// Updates an existing entity instance in the database on behalf of the parent type.
        /// </summary>
        /// <param name="Entity">Any valid database object</param>
        public void Update(T Entity)
        {
            dbset.Attach(Entity);
            db.Entry(Entity).State = System.Data.EntityState.Modified;
            db.Commit();
        }
        public void Update(List<T> Entities)
        {
            foreach (var Entity in Entities)
            {
                dbset.Attach(Entity);
                db.Entry(Entity).State = System.Data.EntityState.Modified;
            }
            db.Commit();
        }
    }
}
